From 94b203346070035340a7b54463120d8f4efa4785 Mon Sep 17 00:00:00 2001 From: tsteven4 <13596209+tsteven4@users.noreply.github.com> Date: Sun, 2 Feb 2020 12:08:40 -0700 Subject: [PATCH] Qt5127 (#489) * update to Qt 5.12.7 switch to online Qt installer. Note the latest Qt online installer, 3.2.1, can crash on macos. https://bugreports.qt.io/projects/QTIFW/issues/QTIFW-1592 For this reason we use the previous installer on macos. * add missing online install script. * update more travis install scripts. * also switch Qt 5.9 builds to 5.9.9. make install target optional in install-qt-online. * fix linux install scripts, enable Qt archive * add new installer dependencies. * fix travis linux install scripts some more. --- .travis.yml | 12 +- tools/Dockerfile_qtio | 13 +- tools/qtci/README.gpsbabel | 2 +- tools/qtci/README.md | 76 +++++---- tools/qtci/extract-qt-installer | 242 ++------------------------ tools/qtci/install-qt | 62 ------- tools/qtci/install-qt-online | 62 +++++++ tools/qtci/qt-install.qs | 256 ++++++++++++++++++++++++++++ tools/travis_install_linux_coverage | 7 +- tools/travis_install_linux_local | 7 +- tools/travis_install_osx | 7 +- 11 files changed, 395 insertions(+), 351 deletions(-) delete mode 100755 tools/qtci/install-qt create mode 100755 tools/qtci/install-qt-online create mode 100644 tools/qtci/qt-install.qs diff --git a/.travis.yml b/.travis.yml index 4a82232f6..5de9798a6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -32,7 +32,7 @@ matrix: compiler: gcc env: - BUILD_TYPE="local" - - QT_VERSION="5.9.8" # 5.12.1 vtesto stmsdf fails with valgrind 3.11.0 which is on xenial + - QT_VERSION="5.9.9" # 5.12.1 vtesto stmsdf fails with valgrind 3.11.0 which is on xenial addons: apt: packages: @@ -45,20 +45,21 @@ matrix: - docbook-xml - docbook-xsl - libgl1-mesa-dev + - libxkbcommon-x11-0 # for qt onliner installer 3.2.1 cache: directories: - $HOME/Cache timeout: 600 - os: osx compiler: clang - env: QT_VERSION="5.9.8" + env: QT_VERSION="5.9.9" cache: directories: - $HOME/Cache timeout: 600 - os: osx compiler: clang - env: QT_VERSION="5.12.6" + env: QT_VERSION="5.12.7" cache: directories: - $HOME/Cache @@ -69,13 +70,14 @@ matrix: compiler: gcc env: - BUILD_TYPE="coverage" - - QT_VERSION="5.9.8" + - QT_VERSION="5.9.9" addons: apt: packages: - libusb-1.0-0-dev - gcovr - lcov + - libxkbcommon-x11-0 # for qt onliner installer 3.2.1 cache: directories: - $HOME/Cache @@ -94,7 +96,7 @@ script: after_success: - cd ${TRAVIS_BUILD_DIR} # only deploy pushes to master or prs that target master. the prs will go to transfr.sh, the pushes go to github. - - if [ "${TRAVIS_OS_NAME}" = "osx" ] && [ "${QT_VERSION}" = "5.12.6" ] && [ "$TRAVIS_BRANCH" = "master" ]; then bash ./tools/uploadtool/upload.sh gui/GPSBabel-*.dmg; fi + - if [ "${TRAVIS_OS_NAME}" = "osx" ] && [ "${QT_VERSION}" = "5.12.7" ] && [ "$TRAVIS_BRANCH" = "master" ]; then bash ./tools/uploadtool/upload.sh gui/GPSBabel-*.dmg; fi branches: except: diff --git a/tools/Dockerfile_qtio b/tools/Dockerfile_qtio index d7addbfde..5824e8a4f 100644 --- a/tools/Dockerfile_qtio +++ b/tools/Dockerfile_qtio @@ -17,13 +17,18 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ libfontconfig1 \ libx11-6 \ libx11-xcb1 \ + libxext6 \ + libxkbcommon0 \ + libxkbcommon-x11-0 \ + libxrender1 \ ca-cacert \ wget \ && rm -rf /var/lib/apt/lists/* # basic build and test tools -COPY ./qtci/install-qt ./qtci/extract-qt-installer /app/ -RUN QT_CI_PACKAGES=qt.qt5.5126.gcc_64,qt.qt5.5126.qtwebengine QT_CI_DOWNLOADER="wget -nv -c" PATH=/app:${PATH} ./install-qt 5.12.6 /opt +COPY ./qtci/install-qt-online ./qtci/extract-qt-installer ./qtci/qt-install.qs /app/ +RUN QT_CI_DOWNLOADER="wget -nv -c" PATH=/app:${PATH} ./install-qt-online "qt.qt5.5127.gcc_64,qt.qt5.5127.qtwebengine" /opt +RUN echo "export PATH=/opt/Qt/5.12.7/gcc_64/bin:$PATH" > /opt/qt-5.12.7.env FROM ubuntu:bionic LABEL maintainer="https://github.com/tsteven4" @@ -84,8 +89,8 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ && rm -rf /var/lib/apt/lists/* # Qt -COPY --from=qt_install /opt/qt-5.12.6.env /opt/qtio.env -COPY --from=qt_install /opt/Qt/5.12.6 /opt/Qt/5.12.6 +COPY --from=qt_install /opt/qt-5.12.7.env /opt/qtio.env +COPY --from=qt_install /opt/Qt/5.12.7 /opt/Qt/5.12.7 COPY --from=qt_install /opt/Qt/Licenses /opt/Qt/Licenses # pkgs needed to generate coverage report: diff --git a/tools/qtci/README.gpsbabel b/tools/qtci/README.gpsbabel index a4bc8393f..614c5bd8d 100644 --- a/tools/qtci/README.gpsbabel +++ b/tools/qtci/README.gpsbabel @@ -1 +1 @@ -The files extract-qt-installer, install-qt, LICENSE, qt-5.9.5-osx, and README.md are from https://github.com/benlau/qtci +The files extract-qt-installer, install-qt, qt-install.qs, LICENSE, and README.md are from https://github.com/benlau/qtci diff --git a/tools/qtci/README.md b/tools/qtci/README.md index 0b82511f5..d1a7df644 100644 --- a/tools/qtci/README.md +++ b/tools/qtci/README.md @@ -4,35 +4,36 @@ This project collects a set of script for building Qt application for Android/iO [![Build Status](https://travis-ci.org/benlau/qtci.svg?branch=master)](https://travis-ci.org/benlau/qtci) Check [.travis.yml](https://github.com/benlau/qtci/blob/master/.travis.yml) to see how it works. -It will demonstrate how to build a apk file using QT-CI scripts. +It will demonstrate how to build an apk file using QT-CI scripts. Installation ============ -Since this project is a collection of script, and the script in bin folder do not have any dependence to each othter. -It is not necessary to clone / download the whole repository into your build environmnet. -You may just copy the script you need from this repository. +Since this project is a collection of scripts, and the script in the bin folder does not have any dependence on each other. +It is not necessary to clone/download the whole repository into your build environment. +You may simply copy the script you need from this repository. **recipes/install-qt** -To automaticly install Qt, you can just donwload 2 scripts and give them permition to be executed. +To automatically install Qt, you can just download 2 scripts and grant them permission for execution. "recipes/install-qt" "bin/extract-qt-installer" -Then just run scritp "recipes/install-qt" with desiered verion of Qt +Then just run script "recipes/install-qt" with the desired version of Qt Example: - bash install-qt 5.9.4 + bash install-qt 5.9.4 + Enviroument variables ===================== -QT_CI_PACKAGES - packages to install. You can check availble packages if set VERBOSE to 1. +QT_CI_PACKAGES - packages to install. You can check available packages if set VERBOSE to 1. Example: - export VERBOSE=1 - export QT_CI_PACKAGES=qt,qt.594,qt.594.gcc_64,qt.594.doc.qtvirtualkeyboard + export VERBOSE=1 + export QT_CI_PACKAGES=qt,qt.594,qt.594.gcc_64,qt.594.doc.qtvirtualkeyboard Setup ===== @@ -48,29 +49,38 @@ Script **(1) bin/extract-qt-installer** -------------------------------- -Extract installer of Qt to target path (for Qt 5.5 or above) +Usage + +``` + extract-qt-installer [--disable-progress-report] qt-installer output_path + extract-qt-installer --list-packages qt-installer +``` + +Extract Qt from the installer to the target path (for Qt 5.5 or above). If --list-packages is given, it will show the available packages from the installer and terminate immediately. Example: - extract-qt-installer qt-opensource-linux-x64-android-5.5.1.run ~/Qt + extract-qt-installer qt-opensource-linux-x64-android-5.5.1.run ~/Qt **Remarks: The installation path must be absolute path** Environment Variables - VERBOSE [Optional] Set to "true" will enable VERBOSE output - QT_CI_PACKAGES [Optional] Select the components to be installed instead of using default (eg. QT_CI_PACKAGES="qt.59.gcc_64") - + VERBOSE [Optional] Set to "true" will enable VERBOSE output + QT_CI_PACKAGES [Optional] Select the components to be installed instead of using default (eg. QT_CI_PACKAGES="qt.59.gcc_64") + QT_CI_LOGIN [Optional] The login name + QT_CI_PASSWORD [Optional] The password of login +The arguments and environment required could be different due to the installer changes. Check the recipes folder or the wiki of known issues to find out the correct setting. **(2) bin/extract-ifw** -------------------------------- -Extract installer of "Qt installer framework" to target path +Extract installer of "Qt installer framework" to the target path Example: - extract-ifw qt-installer-framework-opensource-1.5.0-x64.run ~/QtIfw + extract-ifw qt-installer-framework-opensource-1.5.0-x64.run ~/QtIfw **(3) bin/install-android-sdk** -------------------------------- @@ -79,7 +89,7 @@ Download and install Android SDK Example: - install-android-sdk platform-tool,build-tools-20.0.0,android-19 + install-android-sdk platform-tool,build-tools-20.0.0,android-19 **(4) bin/build-android-gradle-project** -------------------------------- @@ -88,14 +98,14 @@ Build a Qt Android project and sign the APK Usage: - build-android-gradle-project project.pro + build-android-gradle-project project.pro Required Environment Variables - QT_HOME [Required] The home directory of installed Qt. (e.g ~/Qt/5.7) - KEYSTORE [Optional] The location of keystore. If it is set, it will be used to sign the created apk - KEYALIAS [Optional] The alias of the keystore - KEYPASS [Optional] The password of keystore. + QT_HOME [Required] The home directory of installed Qt. (e.g., ~/Qt/5.7) + KEYSTORE [Optional] The location of keystore. If it is set, it will be used to sign the created apk + KEYALIAS [Optional] The alias of the keystore + KEYPASS [Optional] The password of keystore. ANDROID_TARGET_SDK_VERSION [Optional] Target Android SDK version. The default value is "19" (5) bin/increase-android-version-code @@ -105,7 +115,7 @@ Usage increase-android-version-code AndroidManifest.xml -Given a AndroidManifest.xml file, it will increase the value of versionCode field by one. +Given an AndroidManifest.xml file, it will increase the value of the versionCode field by one. (6) bin/run-unittests ---------------------- @@ -114,27 +124,27 @@ Usage run-unittests project.pro -Build and run an unit test project in current folder. If qpm.json was found, it will call `qpm install` first. +Build and run a unit test project in the current folder. If qpm.json were found, it would call `qpm install` first. Recipes ======= -In the folder "recipes", it contains a set of script that could download and install specific Qt toolchains for different environment. (Include Android) +In the folder "recipes", it contains a set of script that could download and install specific Qt toolchains for a different environment. (Include Android) -Please feel free to modify and submit new recipe. +Please feel free to modify and submit a new recipe. Example - apt-get install openjdk-8-jdk p7zip + apt-get install openjdk-8-jdk p7zip - source path.env #Add $PWD/bin and $PWD/recipes to $PATH + source path.env #Add $PWD/bin and $PWD/recipes to $PATH - #Change to installation path + #Change to the installation path - qt-5.5.1-android-19 # Install Qt 5.5.1 and Android SDK - - source qt-5.5.1-android-19.env # Add installed Qt path to $PATH + qt-5.5.1-android-19 # Install Qt 5.5.1 and Android SDK + + source qt-5.5.1-android-19.env # Add installed Qt path to $PATH Reference diff --git a/tools/qtci/extract-qt-installer b/tools/qtci/extract-qt-installer index 8a49925d7..acc8737b5 100755 --- a/tools/qtci/extract-qt-installer +++ b/tools/qtci/extract-qt-installer @@ -10,9 +10,6 @@ function usage() { exit -1 } -unset DISPLAY -echo $DISPLAY - LIST_PACKAGES=0 getopt --test > /dev/null 2>&1 @@ -49,7 +46,7 @@ export PATH=$PATH:$PWD export WORKDIR=$PWD INSTALLER=$1 OUTPUT=$2 -SCRIPT="$(mktemp /tmp/tmp.XXXXXXXXX)" +SCRIPT=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/qt-install.qs PACKAGES=$QT_CI_PACKAGES if [ $LIST_PACKAGES -gt 0 ] @@ -77,244 +74,27 @@ else fi -cat < $SCRIPT - -function abortInstaller() -{ - installer.setDefaultPageVisible(QInstaller.Introduction, false); - installer.setDefaultPageVisible(QInstaller.TargetDirectory, false); - installer.setDefaultPageVisible(QInstaller.ComponentSelection, false); - installer.setDefaultPageVisible(QInstaller.ReadyForInstallation, false); - installer.setDefaultPageVisible(QInstaller.StartMenuSelection, false); - installer.setDefaultPageVisible(QInstaller.PerformInstallation, false); - installer.setDefaultPageVisible(QInstaller.LicenseCheck, false); - - var abortText = "" + qsTr("Installation failed:") + ""; - - var error_list = installer.value("component_errors").split(";;;"); - abortText += ""; - installer.setValue("FinishedText", abortText); -} - -function log() { - var msg = ["QTCI: "].concat([].slice.call(arguments)); - console.log(msg.join(" ")); -} - -function printObject(object) { - var lines = []; - for (var i in object) { - lines.push([i, object[i]].join(" ")); - } - log(lines.join(",")); -} - -var status = { - widget: null, - finishedPageVisible: false, - installationFinished: false -} - -function tryFinish() { - if (status.finishedPageVisible && status.installationFinished) { - if (status.widget.LaunchQtCreatorCheckBoxForm) { - // Disable this checkbox for minimal platform - status.widget.LaunchQtCreatorCheckBoxForm.launchQtCreatorCheckBox.setChecked(false); - } - if (status.widget.RunItCheckBox) { - // LaunchQtCreatorCheckBoxForm may not work for newer versions. - status.widget.RunItCheckBox.setChecked(false); - } - log("Press Finish Button"); - gui.clickButton(buttons.FinishButton); - } -} - -function Controller() { - installer.installationFinished.connect(function() { - status.installationFinished = true; - gui.clickButton(buttons.NextButton); - tryFinish(); - }); - installer.setMessageBoxAutomaticAnswer("OverwriteTargetDirectory", QMessageBox.Yes); - installer.setMessageBoxAutomaticAnswer("installationErrorWithRetry", QMessageBox.Ignore); - - // Allow to cancel installation for arguments --list-packages - installer.setMessageBoxAutomaticAnswer("cancelInstallation", QMessageBox.Yes); -} - -Controller.prototype.WelcomePageCallback = function() { - log("Welcome Page"); - gui.clickButton(buttons.NextButton); - - var widget = gui.currentPageWidget(); - - widget.completeChanged.connect(function() { - gui.clickButton(buttons.NextButton); - }); -} - -Controller.prototype.CredentialsPageCallback = function() { - - var login = installer.environmentVariable("QT_CI_LOGIN"); - var password = installer.environmentVariable("QT_CI_PASSWORD"); - - if (login === "" || password === "") { - gui.clickButton(buttons.CommitButton); - } - - var widget = gui.currentPageWidget(); - - widget.loginWidget.EmailLineEdit.setText(login); - - widget.loginWidget.PasswordLineEdit.setText(password); - - gui.clickButton(buttons.CommitButton); -} - -Controller.prototype.ComponentSelectionPageCallback = function() { - log("ComponentSelectionPageCallback"); - - function list_packages() { - var components = installer.components(); - log("Available components: " + components.length); - var packages = ["Packages: "]; - - for (var i = 0 ; i < components.length ;i++) { - packages.push(components[i].name); - } - log(packages.join(" ")); - } - - if ($LIST_PACKAGES) { - list_packages(); - gui.clickButton(buttons.CancelButton); - return; - } - - log("Select components"); - - function trim(str) { - return str.replace(/^ +/,"").replace(/ *$/,""); - } - - var widget = gui.currentPageWidget(); - - var packages = trim("$PACKAGES").split(","); - if (packages.length > 0 && packages[0] !== "") { - widget.deselectAll(); - var components = installer.components(); - var allfound = true; - for (var i in packages) { - var pkg = trim(packages[i]); - var found = false; - for (var j in components) { - if (components[j].name === pkg) { - found = true; - break; - } - } - if (!found) { - allfound = false; - log("ERROR: Package " + pkg + " not found."); - } else { - log("Select " + pkg); - widget.selectComponent(pkg); - } - } - if (!allfound) { - list_packages(); - // TODO: figure out how to set non-zero exit status. - gui.clickButton(buttons.CancelButton); - return; - } - } else { - log("Use default component list"); - } - - gui.clickButton(buttons.NextButton); -} - -Controller.prototype.IntroductionPageCallback = function() { - log("Introduction Page"); - log("Retrieving meta information from remote repository"); - gui.clickButton(buttons.NextButton); -} - - -Controller.prototype.TargetDirectoryPageCallback = function() { - log("Set target installation page: $OUTPUT"); - var widget = gui.currentPageWidget(); - - if (widget != null) { - widget.TargetDirectoryLineEdit.setText("$OUTPUT"); - } - - gui.clickButton(buttons.NextButton); -} - -Controller.prototype.LicenseAgreementPageCallback = function() { - log("Accept license agreement"); - var widget = gui.currentPageWidget(); - - if (widget != null) { - widget.AcceptLicenseRadioButton.setChecked(true); - } - - gui.clickButton(buttons.NextButton); - -} - -Controller.prototype.ReadyForInstallationPageCallback = function() { - log("Ready to install"); - - // Bug? If commit button pressed too quickly finished callback might not show the checkbox to disable running qt creator - // Behaviour started around 5.10. You don't actually have to press this button at all with those versions, even though gui.isButtonEnabled() returns true. - - gui.clickButton(buttons.CommitButton, 200); -} - -Controller.prototype.PerformInstallationPageCallback = function() { - log("PerformInstallationPageCallback"); - gui.clickButton(buttons.CommitButton); -} - -Controller.prototype.FinishedPageCallback = function() { - log("FinishedPageCallback"); - - var widget = gui.currentPageWidget(); - - // Bug? Qt 5.9.5 and Qt 5.9.6 installer show finished page before the installation completed - // Don't press "finishButton" immediately - - status.finishedPageVisible = true; - status.widget = widget; - tryFinish(); -} - -EOF chmod u+x $1 +if [ -n "$QT_CI_DEBUG" ] +then + $INSTALLER -v --script $SCRIPT QTCI_LIST_PACKAGES="$LIST_PACKAGES" QTCI_PACKAGES="$PACKAGES" QTCI_OUTPUT="$OUTPUT" | grep "\(QTCI\|operation\)" + exit 0 +fi + +unset DISPLAY if [ -n "$DISABLE_PROGRESS_REPORT" ] then - QT_QPA_PLATFORM=minimal $INSTALLER $ARGS --script $SCRIPT + QT_QPA_PLATFORM=minimal $INSTALLER --script $SCRIPT QTCI_LIST_PACKAGES="$LIST_PACKAGES" QTCI_PACKAGES="$PACKAGES" QTCI_OUTPUT="$OUTPUT" else ARGS="-v" if [ -n "$VERBOSE" ] then - QT_QPA_PLATFORM=minimal $INSTALLER $ARGS --script $SCRIPT + QT_QPA_PLATFORM=minimal $INSTALLER $ARGS --script $SCRIPT QTCI_LIST_PACKAGES="$LIST_PACKAGES" QTCI_PACKAGES="$PACKAGES" QTCI_OUTPUT="$OUTPUT" else - QT_QPA_PLATFORM=minimal $INSTALLER $ARGS --script $SCRIPT | grep "\(QTCI\|operation\)" + QT_QPA_PLATFORM=minimal $INSTALLER $ARGS --script $SCRIPT QTCI_LIST_PACKAGES="$LIST_PACKAGES" QTCI_PACKAGES="$PACKAGES" QTCI_OUTPUT="$OUTPUT" | grep "\(QTCI\|operation\)" fi fi diff --git a/tools/qtci/install-qt b/tools/qtci/install-qt deleted file mode 100755 index 0a09064fd..000000000 --- a/tools/qtci/install-qt +++ /dev/null @@ -1,62 +0,0 @@ -#!/bin/bash -e -# Reference: -# https://github.com/musescore/MuseScore/blob/master/build/travis/job_macos/install.sh - -QT_VERSION=${1:-5.12.0} -QT_TARGET_CATALOG=${2:-$PWD} -QT_CI_DOWNLOADER=${QT_CI_DOWNLOADER:-"wget -c -N"} - -QT_MAJOR_VERSION=$(echo ${QT_VERSION} | cut -d "." -f 1) -QT_MINOR_VERSION=$(echo ${QT_VERSION} | cut -d "." -f 2) -if [ "$(uname)" = "Darwin" ]; then - if { [ "${QT_MAJOR_VERSION}" -eq 5 ] && [ "${QT_MINOR_VERSION}" -ge 9 ]; } || [ "${QT_MAJOR_VERSION}" -ge 6 ]; then - # this was good from 5.9.0 through at least 5.12.0 - DOWNLOAD_URL=https://download.qt.io/archive/qt/${QT_MAJOR_VERSION}.${QT_MINOR_VERSION}/${QT_VERSION}/qt-opensource-mac-x64-${QT_VERSION}.dmg - else - # this was good from 5.2.1 through 5.8.0 - DOWNLOAD_URL=https://download.qt.io/archive/qt/${QT_MAJOR_VERSION}.${QT_MINOR_VERSION}/${QT_VERSION}/qt-opensource-mac-x64-clang-${QT_VERSION}.dmg - fi - COMPILER=clang_64 -elif [ "$(uname)" = "Linux" ]; then - # this was good from 5.2.1 through at least 5.12.0 - DOWNLOAD_URL=https://download.qt.io/archive/qt/${QT_MAJOR_VERSION}.${QT_MINOR_VERSION}/${QT_VERSION}/qt-opensource-linux-x64-${QT_VERSION}.run - COMPILER=gcc_64 -else - echo "Unsupported system." >&2 - exit 1 -fi -INSTALLER=$(basename $DOWNLOAD_URL) -ENVFILE=${QT_TARGET_CATALOG}/qt-${QT_VERSION}.env - -echo Downloading Qt -${QT_CI_DOWNLOADER} ${DOWNLOAD_URL} || exit 1 - -echo Installing Qt -if [ "$(uname)" = "Darwin" ]; then - INSTALLER_NAME=${INSTALLER%.*} - APPFILE=/Volumes/${INSTALLER_NAME}/${INSTALLER_NAME}.app/Contents/MacOS/${INSTALLER_NAME} - hdiutil attach ${PWD}/${INSTALLER} - extract-qt-installer $APPFILE ${QT_TARGET_CATALOG}/Qt - # workaround apparent exit of extract-qt-installer before finished, - # which results in hdiutil "hdiutil: couldn't unmount "disk1" - Resource busy" - # and the install resources not being available. - #hdiutil detach /Volumes/${INSTALLER_NAME} - count=0 - until hdiutil detach /Volumes/${INSTALLER_NAME} || [ $count -ge 12 ] - do - echo "Wait and attempt to detach again" - count=`expr $count + 1` - sleep 5 - done -elif [ "$(uname)" = "Linux" ]; then - extract-qt-installer ${PWD}/${INSTALLER} ${QT_TARGET_CATALOG}/Qt -fi - -echo Create ${ENVFILE} -if [ -d "${QT_TARGET_CATALOG}/Qt/${QT_VERSION}/${COMPILER}/bin" ]; then - echo "export PATH=${QT_TARGET_CATALOG}/Qt/${QT_VERSION}/${COMPILER}/bin:$PATH" > ${ENVFILE} -elif [ -d "${QT_TARGET_CATALOG}/Qt/${QT_MAJOR_VERSION}.${QT_MINOR_VERSION}/${COMPILER}/bin" ]; then - # some packages use an abbreviated version x.y in the path instead of x.y.z - echo "export PATH=${QT_TARGET_CATALOG}/Qt/${QT_MAJOR_VERSION}.${QT_MINOR_VERSION}/${COMPILER}/bin:$PATH" > ${ENVFILE} -fi - diff --git a/tools/qtci/install-qt-online b/tools/qtci/install-qt-online new file mode 100755 index 000000000..63d686d73 --- /dev/null +++ b/tools/qtci/install-qt-online @@ -0,0 +1,62 @@ +#!/bin/bash -e +# Install Qt by online installer + +function usage() { + echo "Usage:" + echo "install-qt-online \"packages\" [output_path [qt_installer_version]]" + echo "Examples:" + echo "install-qt-online \"qt.qt5.5121.gcc_64\"" + echo "install-qt-online \"qt.qt5.5121.gcc_64\" /opt/Qt" + echo "install-qt-online \"qt.qt5.5121.gcc_64\" /opt/Qt latest" + echo "install-qt-online \"qt.qt5.5121.gcc_64\" /opt/Qt 3.1.1" + exit -1 +} + +if [ $# -lt 1 ] +then + usage +fi + +export QT_CI_PACKAGES=${1} +QT_TARGET_CATALOG=${2:-$PWD} +INSTALLER_VERSION=${3:-latest} # lastest or a version triplet, e.g. 3.1.1 +QT_CI_DOWNLOADER=${QT_CI_DOWNLOADER:-"wget -c -N"} + +if [ "$(uname)" = "Darwin" ]; then + if [ "${INSTALLER_VERSION}" = "latest" ]; then + DOWNLOAD_URL=https://download.qt.io/official_releases/online_installers/qt-unified-mac-x64-online.dmg + else + DOWNLOAD_URL=https://download.qt.io/archive/online_installers/$(echo ${INSTALLER_VERSION} | cut -d . -f1-2)/qt-unified-mac-x64-${INSTALLER_VERSION}-online.dmg + fi + COMPILER=clang_64 +elif [ "$(uname)" = "Linux" ]; then + if [ "${INSTALLER_VERSION}" = "latest" ]; then + DOWNLOAD_URL=https://download.qt.io/official_releases/online_installers/qt-unified-linux-x64-online.run + else + DOWNLOAD_URL=https://download.qt.io/archive/online_installers/$(echo ${INSTALLER_VERSION} | cut -d . -f1-2)/qt-unified-linux-x64-${INSTALLER_VERSION}-online.run + fi + COMPILER=gcc_64 +else + echo "Unsupported system." >&2 + exit 1 +fi + +INSTALLER=$(basename $DOWNLOAD_URL) + +echo Downloading Qt +${QT_CI_DOWNLOADER} ${DOWNLOAD_URL} || exit 1 + +echo Installing Qt + +if [ "$(uname)" = "Darwin" ]; then + hdiutil attach ${PWD}/${INSTALLER} -plist > minfo.plist + MOUNTPOINT=$(/usr/libexec/PlistBuddy -c "Print :system-entities:0:mount-point" minfo.plist || \ + /usr/libexec/PlistBuddy -c "Print :system-entities:1:mount-point" minfo.plist || \ + /usr/libexec/PlistBuddy -c "Print :system-entities:2:mount-point" minfo.plist) + INSTALLER_NAME=$(basename "${MOUNTPOINT}") + APPFILE="${MOUNTPOINT}"/${INSTALLER_NAME}.app/Contents/MacOS/${INSTALLER_NAME} + extract-qt-installer "$APPFILE" "${QT_TARGET_CATALOG}/Qt" + hdiutil detach "${MOUNTPOINT}" +elif [ "$(uname)" = "Linux" ]; then + extract-qt-installer ${PWD}/${INSTALLER} "${QT_TARGET_CATALOG}/Qt" +fi diff --git a/tools/qtci/qt-install.qs b/tools/qtci/qt-install.qs new file mode 100644 index 000000000..d711157d1 --- /dev/null +++ b/tools/qtci/qt-install.qs @@ -0,0 +1,256 @@ +// QT-CI Project +// License: Apache-2.0 +// https://github.com/benlau/qtci + +function log() { + var msg = ["QTCI: "].concat([].slice.call(arguments)); + console.log(msg.join(" ")); +} + +function printObject(object) { + var lines = []; + for (var i in object) { + lines.push([i, object[i]].join(" ")); + } + log(lines.join(",")); +} + +var status = { + widget: null, + finishedPageVisible: false, + installationFinished: false +} + +function tryFinish() { + if (status.finishedPageVisible && status.installationFinished) { + if (status.widget.LaunchQtCreatorCheckBoxForm) { + // Disable this checkbox for minimal platform + status.widget.LaunchQtCreatorCheckBoxForm.launchQtCreatorCheckBox.setChecked(false); + } + if (status.widget.RunItCheckBox) { + // LaunchQtCreatorCheckBoxForm may not work for newer versions. + status.widget.RunItCheckBox.setChecked(false); + } + log("Press Finish Button"); + gui.clickButton(buttons.FinishButton); + } +} + +function Controller() { + installer.installationFinished.connect(function() { + status.installationFinished = true; + gui.clickButton(buttons.NextButton); + tryFinish(); + }); + installer.setMessageBoxAutomaticAnswer("OverwriteTargetDirectory", QMessageBox.Yes); + installer.setMessageBoxAutomaticAnswer("installationErrorWithRetry", QMessageBox.Ignore); + installer.setMessageBoxAutomaticAnswer("XcodeError", QMessageBox.Ok); + + // Allow to cancel installation for arguments --list-packages + installer.setMessageBoxAutomaticAnswer("cancelInstallation", QMessageBox.Yes); +} + +Controller.prototype.WelcomePageCallback = function() { + log("Welcome Page"); + + gui.clickButton(buttons.NextButton); + + var widget = gui.currentPageWidget(); + + /* + Online installer 3.0.6 + - It must disconnect the completeChanged callback after used, otherwise it will click the 'next' button on another pages + */ + var callback = function() { + gui.clickButton(buttons.NextButton); + widget.completeChanged.disconnect(callback); + } + + widget.completeChanged.connect(callback); +} + +Controller.prototype.CredentialsPageCallback = function() { + + var login = installer.environmentVariable("QT_CI_LOGIN"); + var password = installer.environmentVariable("QT_CI_PASSWORD"); + + if (login === "" || password === "") { + gui.clickButton(buttons.CommitButton); + } + + var widget = gui.currentPageWidget(); + + widget.loginWidget.EmailLineEdit.setText(login); + + widget.loginWidget.PasswordLineEdit.setText(password); + + gui.clickButton(buttons.CommitButton); +} + +Controller.prototype.ComponentSelectionPageCallback = function() { + log("ComponentSelectionPageCallback"); + + function list_packages() { + var components = installer.components(); + log("Available components: " + components.length); + var packages = ["Packages: "]; + + for (var i = 0; i < components.length; i++) { + packages.push(components[i].name); + } + log(packages.join(" ")); + } + + var widget = gui.currentPageWidget(); + + var archiveCheckBox = gui.findChild(widget, "Archive"); + var latestCheckBox = gui.findChild(widget, "Latest releases"); + var fetchButton = gui.findChild(widget, "FetchCategoryButton"); + + if (archiveCheckBox != null) { + // check archive + archiveCheckBox.click(); + } + if (latestCheckBox != null) { + // uncheck latest + latestCheckBox.click(); + } + if (fetchButton != null) { + fetchButton.click() + } + + if (installer.value("QTCI_LIST_PACKAGES", "0") != "0") { + list_packages(); + gui.clickButton(buttons.CancelButton); + return; + } + + log("Select components"); + + function trim(str) { + return str.replace(/^ +/, "").replace(/ *$/, ""); + } + + var packages = trim(installer.value("QTCI_PACKAGES")).split(","); + if (packages.length > 0 && packages[0] !== "") { + widget.deselectAll(); + var components = installer.components(); + var allfound = true; + for (var i in packages) { + var pkg = trim(packages[i]); + var found = false; + for (var j in components) { + if (components[j].name === pkg) { + found = true; + break; + } + } + if (!found) { + allfound = false; + log("ERROR: Package " + pkg + " not found."); + } else { + log("Select " + pkg); + widget.selectComponent(pkg); + } + } + if (!allfound) { + list_packages(); + // TODO: figure out how to set non-zero exit status. + gui.clickButton(buttons.CancelButton); + return; + } + } else { + log("Use default component list"); + } + + gui.clickButton(buttons.NextButton); +} + +Controller.prototype.IntroductionPageCallback = function() { + log("Introduction Page"); + log("Retrieving meta information from remote repository"); + + /* + Online installer 3.0.6 + - Don't click buttons.NextButton directly. It will skip the componenet selection. + */ + + if (installer.isOfflineOnly()) { + gui.clickButton(buttons.NextButton); + } +} + +Controller.prototype.TargetDirectoryPageCallback = function() { + var output = installer.value("QTCI_OUTPUT"); + log("Set target installation page: " + output); + var widget = gui.currentPageWidget(); + + if (widget != null) { + widget.TargetDirectoryLineEdit.setText(output); + } + + gui.clickButton(buttons.NextButton); +} + +Controller.prototype.LicenseAgreementPageCallback = function() { + log("Accept license agreement"); + var widget = gui.currentPageWidget(); + + if (widget != null) { + widget.AcceptLicenseRadioButton.setChecked(true); + } + + gui.clickButton(buttons.NextButton); +} + +Controller.prototype.ReadyForInstallationPageCallback = function() { + log("Ready to install"); + + // Bug? If commit button pressed too quickly finished callback might not show the checkbox to disable running qt creator + // Behaviour started around 5.10. You don't actually have to press this button at all with those versions, even though gui.isButtonEnabled() returns true. + gui.clickButton(buttons.CommitButton, 200); +} + +Controller.prototype.PerformInstallationPageCallback = function() { + log("PerformInstallationPageCallback"); + gui.clickButton(buttons.CommitButton); +} + +Controller.prototype.FinishedPageCallback = function() { + log("FinishedPageCallback"); + + var widget = gui.currentPageWidget(); + + // Bug? Qt 5.9.5 and Qt 5.9.6 installer show finished page before the installation completed + // Don't press "finishButton" immediately + status.finishedPageVisible = true; + status.widget = widget; + tryFinish(); +} + +// Telemetry disabled +Controller.prototype.DynamicTelemetryPluginFormCallback = function() +{ + log("TelemetryPluginFormCallback"); + var page = gui.pageWidgetByObjectName("DynamicTelemetryPluginForm"); + page.statisticGroupBox.disableStatisticRadioButton.setChecked(true); + gui.clickButton(buttons.NextButton); +} + +// On windows installs there is a page about the start menu. +Controller.prototype.StartMenuDirectoryPageCallback = function() { + log("StartMenuDirectoryPageCallback"); + gui.clickButton(buttons.NextButton); +} + +// qt online installer 3.2.1: open source users must now accept the open +// source obligations. +// https://www.qt.io/blog/qt-online-installer-3.2.1-released +Controller.prototype.ObligationsPageCallback = function() +{ + log("ObligationsPageCallback"); + var page = gui.pageWidgetByObjectName("ObligationsPage"); + page.obligationsAgreement.setChecked(true); + page.completeChanged(); + gui.clickButton(buttons.NextButton); +} diff --git a/tools/travis_install_linux_coverage b/tools/travis_install_linux_coverage index 1eee42d85..2620ad494 100755 --- a/tools/travis_install_linux_coverage +++ b/tools/travis_install_linux_coverage @@ -41,10 +41,7 @@ if [ -d "${QTDIR}/bin" ]; then else rm -fr ${CACHEDIR} mkdir -p ${CACHEDIR} - pushd ${CACHEDIR} - # install-qt creates the install at $PWD/Qt. - QT_CI_PACKAGES=qt.qt5.${QT_VERSION_SHORT}.gcc_64 QT_CI_DOWNLOADER="wget -nv -c" PATH=${TRAVIS_BUILD_DIR}/tools/qtci:${PATH} install-qt ${QT_VERSION} - popd + QT_CI_DOWNLOADER="wget -nv -c" PATH=${TRAVIS_BUILD_DIR}/tools/qtci:${PATH} install-qt-online "qt.qt5.${QT_VERSION_SHORT}.gcc_64" ${CACHEDIR} + echo "export PATH=${QTDIR}/bin:$PATH" > ${CACHEDIR}/qt-${QT_VERSION}.env validate - rm ${CACHEDIR}/qt-opensource*.run fi diff --git a/tools/travis_install_linux_local b/tools/travis_install_linux_local index 359a42cf6..65b5e83b7 100755 --- a/tools/travis_install_linux_local +++ b/tools/travis_install_linux_local @@ -41,12 +41,9 @@ if [ -d "${QTDIR}/bin" ]; then else rm -fr ${CACHEDIR} mkdir -p ${CACHEDIR} - pushd ${CACHEDIR} - # install-qt creates the install at $PWD/Qt. - QT_CI_PACKAGES=qt.qt5.${QT_VERSION_SHORT}.gcc_64,qt.qt5.${QT_VERSION_SHORT}.qtwebengine QT_CI_DOWNLOADER="wget -nv -c" PATH=${TRAVIS_BUILD_DIR}/tools/qtci:${PATH} install-qt ${QT_VERSION} - popd + QT_CI_DOWNLOADER="wget -nv -c" PATH=${TRAVIS_BUILD_DIR}/tools/qtci:${PATH} install-qt-online "qt.qt5.${QT_VERSION_SHORT}.gcc_64,qt.qt5.${QT_VERSION_SHORT}.qtwebengine" ${CACHEDIR} + echo "export PATH=${QTDIR}/bin:$PATH" > ${CACHEDIR}/qt-${QT_VERSION}.env validate - rm ${CACHEDIR}/qt-opensource*.run fi # prepare locale for test_encoding_latin1, requires locales package. diff --git a/tools/travis_install_osx b/tools/travis_install_osx index fa0a8dc93..1c7368007 100755 --- a/tools/travis_install_osx +++ b/tools/travis_install_osx @@ -41,10 +41,7 @@ if [ -d "${QTDIR}/bin" ]; then else rm -fr ${CACHEDIR} mkdir -p ${CACHEDIR} - pushd ${CACHEDIR} - # install-qt creates the install at $PWD/Qt. - QT_CI_PACKAGES=qt.qt5.${QT_VERSION_SHORT}.clang_64,qt.qt5.${QT_VERSION_SHORT}.qtwebengine QT_CI_DOWNLOADER="wget -nv -c" PATH=${TRAVIS_BUILD_DIR}/tools/qtci:${PATH} install-qt ${QT_VERSION} - popd + QT_CI_DOWNLOADER="wget -nv -c" PATH=${TRAVIS_BUILD_DIR}/tools/qtci:${PATH} install-qt-online "qt.qt5.${QT_VERSION_SHORT}.clang_64,qt.qt5.${QT_VERSION_SHORT}.qtwebengine" "${CACHEDIR}" 3.1.1 + echo "export PATH=${QTDIR}/bin:$PATH" > ${CACHEDIR}/qt-${QT_VERSION}.env validate - rm ${CACHEDIR}/qt-opensource*.dmg fi -- 2.30.2